from point import *

# for a given board size:
# - given a size, how many handicap stones are allowed?
#   - (this number is[will be] also used for drawing the dots on the board)
# - given a size and a number of stones, say which points get handicap stones

# the range of size and handicaps allowed should be at least what gnugo allows
# (size = 5-19, no handicap allowed for size=5,6, max handicap for 19x19 is 9.)

# ----------------------------------------

# ASSUME: that boards are always rectangular
# ASSUME: that handicaps are never 1 (which would be silly) (unless size=5)

# on which intersections to put the stones; if size<THRESH(??), use only up to 5.
HANDICAP_PLACEMENT = [
  "",
  "",
  "ab",
  "abc",
  "abcd",
  "abcdi",
  "abcdef",
  "abcdefi",
  "abcdefgh",
  "abcdefghi",
]

# see http://senseis.xmp.net/?Handicap for the positions

# the positions are:
#   d g a
#   f i e
#   b h c
HANDICAP_POSITIONS = [ # (col,row) pairs -- 0-2 for each
  [ 2, 2 ], # a
  [ 0, 0 ], # b
  [ 2, 0 ], # c
  [ 0, 2 ], # d
  [ 2, 1 ], # e
  [ 0, 1 ], # f
  [ 1, 2 ], # g
  [ 1, 0 ], # h
  [ 1, 1 ], # i
]

# RULE: for boardsize 11 and smaller, they go on 3,3 points; for 12 and larger, on the 4,4

# (why not apply it directly?  because i need it for drawing the hoshi, too.)

# note: when using this for drawing dots on the board, cache the
# results -- i probably can't make it super-fast here.

# when drawing the dots on the board, you want to put them at each of:
# get_handicap(size, get_max_handicap(size));


#
#  - hook things up so komi is passed along, too
#
#  - maybe replace draw_hoshi() (in goban.cpp) with asking handicap where to draw them
#    - cache, to save time?  (nah, only if profiling shows it's a problem.)
#
#  - start replacing other uses of (col,row) with point_t
#    - especially in any sort of communications protocol -- like gnugo.cpp
#    - (add features as needed to make it useful)
#

# maximum number of handicap stones you can use: 5, or 9, depending on size
def get_max_handicap(size):
    if (size < 13):
        num = 4
        if size%2 == 1:
            num += 1
    else:
        num = 4
        if size%2 == 1:
            num += 5
    return num

# TODO: add a "get-max-standard-handicap" function, so you can do 22-point handicaps

def get_handicap(size, number):
    # special cases ...
    if size < 5:
        return []
    elif size == 5:
        return [Point(str='C3')]

    if size <= 11:
        distance_from_edge = 3
    else:
        distance_from_edge = 4

    if number < 0:
        number = 0
    if number > get_max_handicap(size):
        number = get_max_handicap(size)

    # the three coordinates at which a handicap stone can be
    abc = [distance_from_edge - 1,
           (size - 1) / 2,
           size - distance_from_edge]

    result = []

    for letter in HANDICAP_PLACEMENT[number]:
        index = ord(letter) - ord('a')

        x = abc[HANDICAP_POSITIONS[index][0]]
        y = abc[HANDICAP_POSITIONS[index][1]]

        result += [Point(x, y, size=size)]

    return result
